<?php

namespace App\Http\Controllers\Api;

use App\Address;
use App\Cart;
use App\Commission;
use App\Goods;
use App\GroupBuy;
use App\GroupBuyItem;
use App\GroupMaster;
use App\Http\Controllers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Jobs\CancelOrderJob;
use App\Order;
use App\OrderDetail;
use App\Services\CalRateService;
use App\Services\cityService;
use App\Services\RefundService;
use App\Share;
use App\Sku;
use App\User;
use App\UserCoupon;
use Carbon\Carbon;
use http\Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;

class OrderController extends Controller
{
    use ApiResponse;

    public $uid;
    public $cityService, $refundService;

    /**
     * OrderController constructor.
     */
    public function __construct(cityService $cityService, RefundService $refundService)
    {
        $this->uid = auth('api')->id();
        $this->cityService = $cityService;
        $this->refundService = $refundService;
    }
    //订单列表

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $status = $request->get('status');
        $list = Order::with('detail')->where('uid', $this->uid)->when($status, function ($query) use ($status) {
            switch ($status) {
                case 0:
                    return $query;
                    break;
                case 1:
                    return $query->where('status', 0);
                    break;
                case 2:
                    return $query->where([['status', '=', 1], ['deliveryStatus', '=', 0]]);
                    break;
                case 3:
                    return $query->where([['status', '=', 1], ['deliveryStatus', '=', 1], ['receivingStatus', '=', 0]]);
                    break;
                case 9:
                    return $query->where([['status', '=', 1], ['receivingStatus', '=', 1]])->whereNull('all_eva');
                    break;
            }
        })->latest()->paginate($request->get('size', 10));
        return $this->data($list);
    }

    /**
     * @param $order_number
     * @return \Illuminate\Http\JsonResponse
     */
    public function show($order_number)
    {
        $result = Order::with('detail')->where('order_number', $order_number)->first();
        return $this->data($result);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmOrder(Request $request)
    {
        $now_buy = $request->get('now_buy');
        $has_real_goods = 0;
        $money = 0;
        $group_id = $request->get('group_id');
        $number = $request->get('number', 1);
        $group_master_id = $request->get('group_master_id');
        $sku_id = $request->get('sku_id');
        //理解购买
        if ($now_buy) {
            $goods_info = Goods::where('status', 1)->where('id', $request->get('goods_id'))->first();
            if (!$goods_info) {
                return $this->message_error("商品已下架");
            }
            if ($sku_id) {
                $sku = Sku::where('id', $sku_id)->first();
            } else {
                $sku = [];
            }
            if ($goods_info['type'] == 0) {
                $has_real_goods = 1;
            }

            $data = [[
                'goods_id' => $goods_info['id'],
                'number' => $request->get('number', 1),
                'price' => $sku ? $sku['price'] : $goods_info['price'],
                'cover' => $goods_info['cover'],
                'goods_name' => $goods_info['name'],
                'sku' => $sku,
                'sku_id' => $sku_id,
                'type' => $goods_info['type']
            ]];
            $money = $sku ? $sku->price : $goods_info['price'];
        } elseif ($group_id || $group_master_id) {
            $group = GroupBuy::find($group_id);
            if ($sku_id) {
                $sku = Sku::find($sku_id);
            } else {
                $sku = [];
            }
            $goods_info = Goods::where('status', 1)->where('id', $group['goods_id'])->first();
            $data = [[
                'goods_id' => $goods_info['id'],
                'number' => $request->get('number', 1),
                'price' => ceil($sku ? $sku->price * $group->price_discount / 100 : $goods_info['price'] * $group->price_discount / 100),
                'cover' => $goods_info['cover'],
                'goods_name' => $goods_info['name'],
                'sku' => $sku,
                'sku_id' => $sku_id,
                'type' => $goods_info['type']
            ]];
            if ($goods_info['type'] == 0) {
                $has_real_goods = 1;
            }
            $money = ceil($sku ? $sku->price * $group->price_discount / 100 : $goods_info['price'] * $group->price_discount / 100) * $number;
        } else {
            $data = Cart::with('sku')->where('uid', $this->uid)->where('checked', 1)->get();
            $money = $data->sum(function ($product) {
                return $product['price'] * $product['number'];
            });
            //0是正常商品 1是虚拟商品
            $subset = $data->reject(function ($item, $key) {
                return $item->type == 1;
            });
            if (count($subset) > 0) {
                $has_real_goods = 1;
            }
        }
        $result = [
            'list' => $data,
            'has_real_goods' => $has_real_goods,
            'total' => $money
        ];
        return $this->data($result);

    }

    public function update($order_number, Request $request)
    {
        Order::where('order_number', $order_number)->update($request->all());
        if ($request->get('status') == -1) {
            $order = Order::find($order_number);
            if ($order->status == 1) {
                //
                $refund_number = $this->refundService->refund($order_number, "取消订单");
                if ($refund_number) {
                    $order->refund_number = $refund_number;
                    $order->save();
                    return $this->message_success("取消成功");
                } else {
                    return $this->message_error("取消失败");
                }
            }
        }
        if ($request->get('receivingStatus') == 1) {
            Commission::where('order_number', $order_number)->update(['status' => 1]);
        }

        return $this->message_success('修改成功');

    }

    public function store(Request $request)
    {
        $end_time=Carbon::createFromTimeString("2020-11-19 00:00:00");
        $has_real_goods = $request->get('has_real_goods');
        $share_uid = $request->get('share_uid');
        $coupon_id = $request->get('user_coupon_id', 0);
        if (Carbon::now()->lte($end_time)){
            $coupon_id=[];
        }
        $address = [];
        $is_group = 0;
        if ($has_real_goods) {
            $adr_id = $request->get('adr_id');
            if (!$adr_id) {
                return $this->message_error("请选择收货地址");
            }
            $address = Address::where('uid', $this->uid)->where('id', $adr_id)->first();
        }

        $goods_id = $request->get('goods_id');
        $group_id = $request->get('group_id');
        $number = $request->get('number', 1);
        $group_master_id = $request->get('group_master_id');
        $sku_id = $request->get('sku_id');
//        $coupon_id = $request->get('coupon_id', 0);
//        $cost_wallet = $request->get('cost_wallet', 0);
        $list = [];
        if ($goods_id) {
            $list = Goods::where('id', $goods_id)->where('status', 1)->first();
        }
        if ($goods_id) {
            $goods_info = Goods::where('status', 1)->first();
            if (!$goods_info) {
                return $this->message_error("商品已下架");
            }
            if ($sku_id) {
                $sku = Sku::where('id', $sku_id)->first();
                if ($sku['stock'] - 1 < 0) {
                    return $this->message_error("库存不足");
                }
            } else {
                if ($goods_info['stock'] - 1 < 0) {
                    return $this->message_error("库存不足");
                }
                $sku = [];
            }

            $list = [[
                'goods_id' => $goods_info['id'],
                'number' => $request->get('number', 1),
                'price' => $sku ? $sku['price'] : $goods_info['price'],
                'cover' => $goods_info['cover'],
                'goods_name' => $goods_info['name'],
                'sku' => $sku,
                'sku_id' => $sku_id,
                'type' => $goods_info['type'],
                'origin_price' => $sku ? $sku['price'] : $goods_info['price'],
            ]];
            $money = $sku ? $sku->price * $request->get('number', 1) : $goods_info['price'] * $request->get('number', 1);
        } elseif ($group_id || $group_master_id) {
            if ($group_master_id) {
                $groupItem = GroupBuyItem::where('uid', $this->uid)->where('group_master_id', $group_master_id)->where('status', 1)->first();
                if ($groupItem) {
                    return $this->message_error("您已参团，请勿重新参团");
                }
            }
            $group = GroupBuy::find($group_id);
            $goods_info = Goods::where('status', 1)->where('id', $group['goods_id'])->first();
            if ($sku_id) {
                $sku = Sku::find($sku_id);
                if ($sku['stock'] - 1 < 0) {
                    return $this->message_error("该类别已售罄");
                }
            } else {
                if ($goods_info['stock'] - 1 < 0) {
                    return $this->message_error("该类别已售罄");
                }
                $sku = [];
            }

            $list = [[
                'goods_id' => $goods_info['id'],
                'number' => $request->get('number', 1),
                'price' => $sku ? $sku->price * $group->price_discount / 100 : $goods_info['price'] * $group->price_discount / 100,
                'cover' => $goods_info['cover'],
                'goods_name' => $goods_info['name'],
                'sku' => $sku,
                'sku_id' => $sku_id,
                'type' => $goods_info['type'],
                'origin_price' => $sku ? $sku->price : $goods_info['price']
            ]];
            $money = ceil($sku ? $sku->price * $group->price_discount / 100 : $goods_info['price'] * $group->price_discount / 100) * $number;
            $is_group = 1;

        } else {
            $list = Cart::with(['sku'])->where([['uid', '=', $this->uid], ['checked', '=', 1]])->get();
            $money = $list->sum(function ($product) {
                return $product['price'] * $product['number'];
            });
            $no_stock = $list->filter(function ($item) {
                if ($item['sku_id']) {
                    $sku = Sku::find($item['sku_id']);
                    if ($sku['stock'] - $item['number'] < 0) {
                        return true;
                    }
                } else {
                    $goods = Goods::find($item['goods_id']);
                    if ($goods['stock'] - $item['number'] < 0) {
                        return true;
                    }
                }
            });
            $no_stock_string = $no_stock->pluck("goods_name")->implode(",");
            if ($no_stock->count() > 0) {
                foreach ($no_stock->toArray() as $key => $value) {
                    Cart::where('id', $value['id'])->update(['checked' => 0]);
                }
                return $this->message_error($no_stock_string . '已售罄');
            }

        }
        $coupon_discount = 0;
        if ($coupon_id && !($group_id || $group_master_id)) {
            if (!is_array($coupon_id)) {
                $coupon_id = [$coupon_id];
            }
            $coupons = UserCoupon::whereIn('id', $coupon_id)->get();
            if ($coupons) {
                foreach ($coupons as $coupon) {
                    if (!empty($coupon->bind_goods)) {
                        $goods_id = collect($list)->pluck("goods_id");
                        $insect = $goods_id->intersect(collect($coupon->bind_goods));
                        if ($insect->isNotEmpty()) {
                            $money -= $coupon->price;
                            $coupon_discount += $coupon->price;
                        } else {
                            return $this->message_error("优惠券无法使用");
                        }
                    } else {
                        if ($money >= $coupon->fill_money) {
                            $money -= $coupon->price;
                            $coupon_discount += $coupon->price;
                        } else {
                            return $this->message_error("优惠券无法使用");
                        }

                    }
                }


            }
        } else {
            $coupon = [];
        }

        $order_number = Carbon::now()->format('YmdHis') . random_int(1000, 9999) . $this->uid;
        $order = [
            'uid' => $this->uid,
            'order_number' => $order_number,
            'order_amount' => $money,
            'pay_amount' => $money,
            'coupon_id' => $coupon_id && !($group_id || $group_master_id) ? $coupon_id : 0,
            'coupon_discount' => $coupon ? $coupon_discount : 0,
            'status' => 0,
            'address_province' => $address ? $this->cityService->getName($address['province']) : "",
            'address_city' => $address ? $this->cityService->getName($address['city']) : "",
            'address_area' => $address ? $this->cityService->getName($address['area']) : "",
            'address_consignee' => $address ? $address['name'] : "",
            'address_phone_number' => $address ? $address['phone_number'] : "",
            'address_detail' => $address ? $address['detail'] : "",
            'deduction_wallet_money' => 0,
            'deduction_wallet' => 0,
            'quantity' => 0,
            'is_group_buy' => $is_group,
            'share_uid' => $share_uid,
            'group_item_id' => 0
        ];
        DB::beginTransaction();
        try {
            $created = Order::create($order);
            $quantity = 0;
            $total_count = collect($list)->count();
            if (!$coupon) {
                $avg_price = 0;
            } else {
                $avg_price = $coupon->price / $total_count;
            }
            if ($share_uid) {
                $share_has_buy = Order::where('uid', $share_uid)->where('status', 1)->count();
                $merchant = User::where('id', $share_uid)->first();

                if ($share_has_buy && !$merchant->is_merchant) {
                    $share_data = [
                        'uid' => $this->uid,
                        'share_uid' => $share_uid,
                        'order_number' => $order_number,
                        'status' => 0,
                    ];
                    Share::create($share_data);
                }

            }
            foreach ($list as $key => $value) {
                $detail = [
                    'order_id' => $order_number,
                    'goods_name' => $value['goods_name'],
                    'goods_id' => $value['goods_id'],
                    'cover' => $value['cover'],
                    'price' => ceil($value['price']) - $avg_price,
                    'number' => $value['number'],
                    'sku_id' => $value['sku_id'],
                    'sku' => !empty($value['sku']) ? $value['sku']['spec_text'] : '',
                    'type' => $value['type'],
                    'origin_price' => ceil(isset($value['origin_price']) ? $value['origin_price'] : $value['price'])
                ];
                $quantity += $value['number'];
                OrderDetail::create($detail);
            }
            if (!$goods_id) {
                Cart::where([['uid', '=', $this->uid], ['checked', '=', 1]])->delete();
            }
            $created->quantity = $quantity;
            if ($coupon_id && !($group_id || $group_master_id)) {
                UserCoupon::where('id', $coupon_id)->update(['status' => 1]);
            }

            if ($group_id || $group_master_id) {
                $group_item_id = $this->make_group_buy($group_id, $group_master_id, $this->uid, $order_number, $money);
                if ($group_item_id) {
                    $created->group_item_id = $group_item_id;
                }
            }
            $created->save();
            DB::commit();
            $job = new CancelOrderJob($created->order_number);
            $job->setDelay(now()->addMinutes(30));
            $this->dispatch($job);

            return $this->data($created);
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::error($order_number . "---订单出错", [$exception->getMessage()]);
            return $this->message_error("下单未成功，请稍后重试");
        }

    }

    private function make_group_buy($group_id, $group_master_id, $uid, $order_id, $price)
    {

        if ($group_master_id) {

            $group_master = GroupMaster::find($group_master_id);
            if ($group_master->current_num + 1 <= $group_master->max_man) {
                $data = [
                    'group_buy_id' => $group_id,
                    'group_master_id' => $group_master_id,
                    'uid' => $uid,
                    'exp_time' => $group_master['end_time'],
                    'status' => 0,
                    'pay_status' => 0,
                    'order_number' => $order_id,
                    'price' => $price,
                    'u_nickname' => auth('api')->user()->nickname
                ];
                $created = GroupBuyItem::create($data);
                Order::where('order_number', $order_id)->update(['group_item_id' => $created->id]);
                return $created->id;
            } else {
                throw new \Exception("开团人数已满");
            }

        } else {
            $group = GroupBuy::find($group_id);
            $start_time = Carbon::now();
            $end_time = $start_time->addDays($group['exp_day']);
            $data = [
                'group_buy_id' => $group_id,
                'uid' => $uid,
                'current_num' => 0,
                'start_time' => $start_time->toDateTimeString(),
                'end_time' => $end_time->toDateTimeString(),
                'min_man' => $group->min_man,
                'max_man' => $group->max_man,
                'status' => 0,
                'goods_id' => $group->goods_id,
                'price_discount' => $group->price_discount
            ];
            $create = GroupMaster::create($data);
            $item = [
                'group_buy_id' => $group_id,
                'group_master_id' => $create->id,
                'uid' => $uid,
                'exp_time' => $end_time->toDateTimeString(),
                'status' => 0,
                'pay_status' => 0,
                'order_number' => $order_id,
                'is_master' => 1,
                'price' => $price,
                'u_nickname' => auth('api')->user()->nickname
            ];
            $created = GroupBuyItem::create($item);
            return $created->id;
        }
    }

    public function express(Request $request)
    {
        $order_number = $request->get('order_number');
        $order = Order::where('order_number', $order_number)->first();
        $data = [
            'order_id' => $order_number,
            'waybill_id' => $order->tracking_no,
            'delivery_id' => "SF"
        ];
        $app = app('wechat.mini_program');
        $result = $app->express->getWaybillTrack($data);
        if (isset($result['errcode'])) {
            return $this->message_error($result['errmsg']);
        }

        return $this->data($result);
    }

    public function check_money(Request $request)
    {
        $coupon_id = $request->get('user_coupon_id', 0);
        $goods_id = $request->get('goods_id');
        $group_id = $request->get('group_id');
        $number = $request->get('number', 1);
        $group_master_id = $request->get('group_master_id');
        $sku_id = $request->get('sku_id');
//        $coupon_id = $request->get('coupon_id', 0);
//        $cost_wallet = $request->get('cost_wallet', 0);
        $list = [];
        if ($goods_id) {
            $list = Goods::where('id', $goods_id)->where('status', 1)->first();
        }
        if ($goods_id) {
            $goods_info = Goods::where('status', 1)->first();
            if ($sku_id) {
                $sku = Sku::where('id', $sku_id)->first();
                if ($sku['stock'] - 1 < 0) {
                    return $this->message_error("库存不足");
                }
            } else {
                if ($goods_info['stock'] - 1 < 0) {
                    return $this->message_error("库存不足");
                }
                $sku = [];
            }
            $money = $sku ? $sku->price * $request->get('number', 1) : $goods_info['price'] * $request->get('number', 1);
        } elseif ($group_id || $group_master_id) {
            $group = GroupBuy::find($group_id);
            $goods_info = Goods::where('status', 1)->where('id', $group['goods_id'])->first();
            if ($sku_id) {
                $sku = Sku::find($sku_id);
            } else {

                $sku = [];
            }

            $money = ceil($sku ? $sku->price * $group->price_discount / 100 : $goods_info['price'] * $group->price_discount / 100) * $number;

        } else {
            $list = Cart::with(['sku'])->where([['uid', '=', $this->uid], ['checked', '=', 1]])->get();
            $money = $list->sum(function ($product) {
                return $product['price'] * $product['number'];
            });
        }
        if ($coupon_id) {
            $coupons = UserCoupon::whereIn('id', $coupon_id)->get();
            if ($coupons) {
                foreach ($coupons as $coupon) {
                    if (!empty($coupon->bind_goods)) {
                        $goods_id = collect($list)->pluck("goods_id");
                        $insect = $goods_id->intersect(collect($coupon->bind_goods));
                        if ($insect->isNotEmpty()) {
                            $money -= $coupon->price;
                        } else {
                            return $this->message_error("优惠券无法使用");
                        }
                    } else {
                        if ($money >= $coupon->fill_money) {
                            $money -= $coupon->price;
                        } else {
                            return $this->message_error("优惠券无法使用");
                        }

                    }
                }


            }
        } else {
            $coupon = [];
        }
        $result = [
            'total_amount' => $money
        ];
        return $this->data($result);
    }

}
